/**
 * Copyright (c) 2018-2023, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: message queue test 
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2023-09-07     JasonHu           Init
 */

#include <test/integration.h>
#define NX_LOG_NAME "mq"
#include <base/log.h>
#include <base/msgqueue.h>
#include <base/thread.h>
#include <base/debug.h>
#include <base/string.h>

#ifdef CONFIG_NX_TEST_INTEGRATION_MSG_QUEUE

NX_PRIVATE NX_MsgQueue *mq0 = NX_NULL;

NX_PRIVATE void Thread1(void *arg)
{
    static int counter = 0;
    int times = 50;
    while (times > 0)
    {
        char buf[32] = {0};
        NX_SNPrintf(buf, 32, "hello, counter = %d.", counter++);
        NX_LOG_I("msg tx: %s\n", buf);
        NX_MsgBuf mbuf = {.payload = buf, .len = NX_StrLen(buf)};
        NX_MsgQueueSend(mq0, &mbuf);
        NX_ThreadSleep(100);
        times--;
    }
    NX_MsgBuf mbufEnd = {.payload = "END", .len = 3};
    NX_MsgQueueSend(mq0, &mbufEnd);
}

NX_PRIVATE void Thread2(void *arg)
{

    while (1)
    {
        char buf[32] = {0};
        NX_MsgBuf mbuf = {.payload = buf, .len = 32};
        NX_MsgQueueRecv(mq0, &mbuf);
        if (NX_StrCmp(buf, "END") == 0)
        {
            break;
        }
        NX_LOG_I("msg rx: %s\n", buf);
        NX_ThreadSleep(50);
    }
}

NX_PRIVATE void Thread3(void *arg)
{
    static int counter = 0;
    int times = 50;
    while (times > 0)
    {
        char buf[32] = {0};
        NX_SNPrintf(buf, 32, "hello, counter = %d.", counter++);
        
        NX_MsgBuf mbuf = {.payload = buf, .len = NX_StrLen(buf)};
        
        if (NX_MsgQueueTrySend(mq0, &mbuf) == NX_EOK)
        {
            NX_LOG_I("msg tx: %s\n", buf);
            NX_ThreadSleep(100);
            times--;
        }
    }
    NX_MsgBuf mbufEnd = {.payload = "END", .len = 3};
    NX_MsgQueueSend(mq0, &mbufEnd);
}

NX_PRIVATE void Thread4(void *arg)
{

    while (1)
    {
        char buf[32] = {0};
        NX_MsgBuf mbuf = {.payload = buf, .len = 32};
        if (NX_MsgQueueTryRecv(mq0, &mbuf) == NX_EOK)
        {
            if (NX_StrCmp(buf, "END") == 0)
            {
                break;
            }
            NX_LOG_I("msg rx: %s\n", buf);
        }
    }
}

NX_INTEGRATION_TEST(NX_MsgQueue)
{
    NX_Thread *t0, *t1;

    mq0 = NX_MsgQueueCreate(32, 4);
    NX_ASSERT(mq0 != NX_NULL);

    t0 = NX_ThreadCreate("t0", Thread1, NX_NULL, NX_THREAD_PRIORITY_NORMAL);
    NX_ASSERT(t0 != NX_NULL);
    t1 = NX_ThreadCreate("t1", Thread2, NX_NULL, NX_THREAD_PRIORITY_NORMAL);
    NX_ASSERT(t1 != NX_NULL);

    NX_ThreadStart(t0);
    NX_ThreadStart(t1);

    NX_ThreadWait(t0, NX_NULL);
    NX_ThreadWait(t1, NX_NULL);

    
    t0 = NX_ThreadCreate("t2", Thread3, NX_NULL, NX_THREAD_PRIORITY_NORMAL);
    NX_ASSERT(t0 != NX_NULL);
    t1 = NX_ThreadCreate("t3", Thread4, NX_NULL, NX_THREAD_PRIORITY_NORMAL);
    NX_ASSERT(t1 != NX_NULL);

    NX_ThreadStart(t0);
    NX_ThreadStart(t1);

    NX_ThreadWait(t0, NX_NULL);
    NX_ThreadWait(t1, NX_NULL);
    return NX_EOK;
}

#endif
